Grundkurs SQL

4.5  Die HAVING-Anweisung

[9]SELECT   abteilung_ID AS Abteilung, MIN(bruttolohn) AS MinLohn,
         MAX(bruttolohn) AS MaxLohn, COUNT(*) AS Anzahl_der_Mitarbeiter
FROM     tbl_mitarbeiter
GROUP BY abteilung_ID

Die Abfrage zeigt uns eine Auflistung der minimalen und maximalen Verdienste sowie die Anzahl der Angestellten jeder Abteilung.

Nun wollen wir aber einige Abteilungen von der Anzeige ausschließen und zwar alle diejenigen, zu denen nur ein Mitarbeiter zählt.
Die Verwendung der WHERE-Anweisung scheidet dabei aus, weil in ihr keine Aggregatfunktionen erlaubt sind! Zum Einsatz kommt hier die HAVING-Anweisung.

[7]SELECT   abteilung_ID AS Abteilung, MIN(bruttolohn) AS MinLohn,
         MAX(bruttolohn) AS MaxLohn, COUNT(*) AS Anzahl_der_Mitarbeiter
FROM     tbl_mitarbeiter
GROUP BY abteilung_ID
HAVING   COUNT(*) > 1

Mit dieser HAVING-Anweisung wird die Anzeige auf diejenigen Abteilungen beschränkt, die mehr als einen Mitarbeiter haben. In unserem Falle fallen damit die Abteilungen 02 und 11 heraus.
Es wäre möglich, den Aliasnamen (Anzahl_der_Mitarbeiter) in der HAVING-Zeile zu verwenden. Leider wird dies wiederum nicht von allen SQL-Dialekten unterstützt, so dass Sie es sich gar nicht erst angewöhnen sollten.
Im Übrigen sei darauf hingewiesen, dass es egal ist, ob die Aggregat-Funktion der HAVING-Anweisung auch in der SELECT-Zeile steht oder nicht.

HAVING oder WHERE

Die Entscheidung zwischen WHERE- und HAVING-Anweisung fällt häufig schwer. Mit der folgenden Anweisung wollen wir die Mitarbeiter aus der Berechnung ausschließen, deren Bruttolohn kleiner gleich 1000 Euro ist. Dies ist natürlich weiterhin ein Fall für die WHERE-Anweisung wobei diese vor dem GROUP BY stehen muss!

[2]SELECT   abteilung_ID AS Abteilung, MIN(bruttolohn) AS MinLohn,
         MAX(bruttolohn) AS MaxLohn, COUNT(*) AS Anzahl_der_Mitarbeiter
FROM     tbl_mitarbeiter
WHERE    bruttolohn > 1000
GROUP BY abteilung_ID
HAVING   COUNT(*) > 1

Dieses Ergebnis könnte etwas verwundern - die oben gemachte Abfrage hatte doch ergeben, dass es in 7 Abteilungen mehr als einen Mitarbeiter gibt und auch der Maximallohn liegt in 6 Abteilungen über 1000 Euro. Um das Resultat zu verstehen muss man also wissen, wie die einzelnen Teile der Abfrage nacheinander abgearbeitet werden:

Die WHERE-Bedingung wird vor dem Bilden der Gruppen ausgeführt und führt dazu, dass bestimmte Datensätze nicht in die Berechnungen einfließen. Angezeigt werden dann nur die die Gruppen (hier Abteilungen), welche der HAVING-Bedingung entsprechen. Diese wird zuletzt angewandt, direkt bevor die Ergebnisse ausgegeben werden – ohne jede Optimierung.

Das Ergebnis erklärt sich also wie folgt:
Durch die WHERE-Bedingung werden alle Datensätze von Mitarbeitern ausgeschlossen, die weniger als oder genau 1000 Euro verdienen. Nur über die übrigen Datensätze wird gruppiert und auch gezählt.
Durch das HAVING bleiben dann nur zwei Abteilungen übrig - von denen wir nun wissen, dass hier mehr als zwei Mitarbeiter mehr als 1000 Euro verdienen. Es ist für das Verständnis des Unterschieds zwischen WHERE und HAVING sehr wichtig, dass Sie diese Argumentation nachvollziehen können. Prüfen Sie deshalb diese Aussage, indem Sie nochmals in die Mitarbeitertabelle schauen.

Die WHERE-Klausel legt Bedingungen für einzelne Datensätze fest, im HAVING führt man nur Bedingungen auf, die für Gruppen gelten. Benutzen Sie kein HAVING für Dinge, die in der WHERE-Klausel stehen sollten.